import * as React from 'react';
import CheckPermissions from './check-permissions';
import AuthorizedRoute from './authorized-route';

type authorityFN = (currentAuthority?: string) => boolean;
type authority = string | Array<string> | authorityFN | Promise<any>;

type IReactComponent<P = any> =
  | React.StatelessComponent<P>
  | React.ComponentClass<P>
  | React.ClassicComponentClass<P>;

interface AuthorizedProps {
  authority: authority;
  noMatch?: React.ReactNode;
}

interface Secured {
  (authority: authority, error?: React.ReactNode): <T extends IReactComponent>(target: T) => T;
}

interface Check {
  <T extends IReactComponent, S extends IReactComponent>(
    authority: authority,
    target: T,
    Exception: S
  ): T | S;
}

class Authorized extends React.Component<AuthorizedProps> {
  static Secured: Secured;
  static AuthorizedRoute: typeof AuthorizedRoute;
  static check: Check;

  render() {
    const { children, authority, noMatch = null } = this.props;
    const childrenRender = typeof children === 'undefined' ? null : children;
    return CheckPermissions(authority, childrenRender as any, noMatch as any);
  }
}

export default Authorized;
